#include <iostream>
#include <vector>
#include <algorithm>
#include <math.h>
#include <unordered_set>
using namespace std;
class Solution
{
public:
    /**
     * @brief 正方形
     *  1.任意两条边的距离相等
     *  2.任意两条边组成的夹角向量相等
     *
     * @param p1
     * @param p2
     * @param p3
     * @param p4
     * @return true
     * @return false
     */
    bool validSquare(vector<int> &p1, vector<int> &p2, vector<int> &p3, vector<int> &p4)
    {
        auto getMod = [=](vector<int> a) -> double
        {
            return sqrt(a[0] * a[0] + a[1] * a[1]);
        };
        auto getDistance = [=](vector<int> a, vector<int> b) -> double
        {
            return sqrt(pow(b[0] - a[0], 2) + pow(b[1] - a[1], 2));
        };

        auto getAngel = [=](vector<int> a, vector<int> b) -> double
        {
            if (0 == getMod(a) || 0 == getMod(b))
            {
                return 0;
            }
            return (a[0] * b[0] + a[1] * b[1]) / (getMod(a) * getMod(b));
        };

        if (getDistance(p1, p2) != getDistance(p3, p4) || getDistance(p2, p3) != getDistance(p1, p4))
        {
            return false;
        }
        if (getAngel(p1, p2) != 0 || abs(getAngel(p2, p3)) != 1)
        {
            cout << getAngel(p1, p2) << " " << getAngel(p2, p3) << endl;
            cout << "angel" << endl;
            return false;
        }

        return true;
    }

    /**
     * @brief 计算四条边和对边的长度
     *
     * @param p1
     * @param p2
     * @param p3
     * @param p4
     * @return true
     * @return false
     */
    bool validSquare_2(vector<int> &p1, vector<int> &p2, vector<int> &p3, vector<int> &p4)
    {
        if (p1 == p2 || p1 == p3 || p1 == p4 || p2 == p3 || p2 == p4 || p3 == p4)
        {
            return false;
        }

        auto getDistance = [=](vector<int> a, vector<int> b) -> int
        {
            return pow(b[0] - a[0], 2) + pow(b[1] - a[1], 2);
        };
        unordered_set<int> distanceSet = {};
        distanceSet.insert(getDistance(p1, p2));
        distanceSet.insert(getDistance(p1, p3));
        distanceSet.insert(getDistance(p1, p4));
        distanceSet.insert(getDistance(p2, p3));
        distanceSet.insert(getDistance(p2, p4));
        distanceSet.insert(getDistance(p3, p4));

        return distanceSet.size() == 2;
    }

    /**
     * @brief 任意三点都是等腰直角三角形 4ms
     *
     * @param p1
     * @param p2
     * @param p3
     * @param p4
     * @return true
     * @return false
     */
    bool validSquare_3(vector<int> &p1, vector<int> &p2, vector<int> &p3, vector<int> &p4)
    {
        if (p1 == p2 || p1 == p3 || p1 == p4 || p2 == p3 || p2 == p4 || p3 == p4)
        {
            return false;
        }

        auto isIsoscelesRightTriangle = [&](vector<int> a, vector<int> b, vector<int> c) -> bool
        {
            int d1 = (a[0] - b[0]) * (a[0] - b[0]) + (a[1] - b[1]) * (a[1] - b[1]);
            int d2 = (a[0] - c[0]) * (a[0] - c[0]) + (a[1] - c[1]) * (a[1] - c[1]);
            int d3 = (c[0] - b[0]) * (c[0] - b[0]) + (c[1] - b[1]) * (c[1] - b[1]);
            return d1 > d2 && d2 == d3 && d1 == d2 + d3 ||
                   d2 > d3 && d1 == d3 && d2 == d1 + d3 ||
                   d3 > d1 && d2 == d1 && d3 == d2 + d1;
        };

        return isIsoscelesRightTriangle(p1, p2, p3) && isIsoscelesRightTriangle(p1, p2, p4) && isIsoscelesRightTriangle(p2, p3, p4) && isIsoscelesRightTriangle(p1, p3, p4);
    }
};
int main()
{
    Solution s;
    vector<int> p1 = {0, 0}, p2 = {1, 1}, p3 = {1, 0}, p4 = {0, 1};
    cout << s.validSquare_3(p1, p2, p3, p4) << endl;
    return 0;
}